在本教程中,您将创建用户能滚动包含在Widget Grid List Box 中的小组件列表的应用程序,并且用户能从该列表选择Widget Item Prefab 表示的小组件。3D 网格列表框 (Grid List Box 3D) 节点提供能在 Kanzi Studio 工程中设置的水平滚动,但您需要定义处理小组件选择的应用程序逻辑。
在该教程的这一步骤中,您将实现在用户点击小组件时处理小组件项选择的功能:
要创建选择小组件的交互处理程序:
ProgrammerTutorialApplication
类中的 onProjectLoaded()
函数后,实现在Widget Grid List Box 中选择小组件的事件处理程序。使用选定小组件的索引,检索Widget Grid List Box 节点的选定小组件。 class ProgrammerTutorialApplication : public ExampleApplication
{
...
private:
//来自Widget Grid List Box 的 ListBox.ItemSelected 消息处理程序。
//将选择的列表框项移到前面。
void onListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments)
{
//从消息参数中检索选定列表框项的索引。
optional<size_t> selectedItemIndex = messageArguments.getSelectedItemIndex();
if (selectedItemIndex)
{
//移除旧回放,以重置值。
//在该教程的下一步实现此函数。
removePlaybacks();
//按其索引检索选定列表框项。
m_selectedItem = m_widgetList->getItem(*selectedItemIndex);
...
}
}
};
void onListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments) { ... if (selectedItemIndex) { ... //计算摄像机动画目标节点的新值,并开始动画。 { //获取当前变换。 Matrix4x4 selectedItemTransformation = m_selectedItem->getFinalTransformation(); //获取摄像机的相对变换目标位置。 SRTValue3D transformationTarget = m_cameraTransformationTarget; //将选定项的位置添加到目标摄像机变换中。 transformationTarget.setTranslation(selectedItemTransformation.getTranslation() - transformationTarget.getTranslation()); //为摄像机创建动画。 m_cameraAnimation = FromToAnimation<SRTValue3D, LinearEasingFunction>::create(getDomain(), chrono::seconds(1), nullopt, transformationTarget); //开始动画。 PropertyAnimationTimelineSharedPtr cameraTimeline = PropertyAnimationTimeline::create(getDomain(), ".", Node3D::RenderTransformationProperty, m_cameraAnimation); SceneGraphTimelinePlaybackContext cameraContext(*m_camera); m_cameraPlayback = cameraTimeline->createPlayback(cameraContext); getDomain()->getRootTimelineClock()->addTimelinePlayback(m_cameraPlayback); } } ... }
onProjectLoaded()
函数中定义。void onListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments) { ... if (selectedItemIndex) { ... //开始选定项的动画。 PropertyAnimationTimelineSharedPtr selectedItemTimeline = PropertyAnimationTimeline::create(getDomain(), ".", Node3D::LayoutTransformationProperty, m_selectedItemAnimation); SceneGraphTimelinePlaybackContext selectedItemContext(*m_selectedItem); m_widgetHighlightPlayback = selectedItemTimeline->createPlayback(selectedItemContext); getDomain()->getRootTimelineClock()->addTimelinePlayback(m_widgetHighlightPlayback); } }
void onListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments)
{
...
if (selectedItemIndex)
{
...
//开始动画以禁用 Back button 输入。
PropertyAnimationTimelineSharedPtr backButtonEnableTimeline = PropertyAnimationTimeline::create(getDomain(), ".", Button3D::HitTestableProperty, m_backButtonEnableAnimation);
SceneGraphTimelinePlaybackContext backButtonEnableContext(*m_backButton);
m_backButtonEnablePlayback = backButtonEnableTimeline->createPlayback(backButtonEnableContext);
getDomain()->getRootTimelineClock()->addTimelinePlayback(m_backButtonEnablePlayback);
}
}
void onListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments) { ... if (selectedItemIndex) { ... //通过将Widget Description Layer 设置为可见,显示小组件描述。 if (m_widgetDescriptionVisibilityPlayback) { getDomain()->getRootTimelineClock()->removeTimelinePlayback(*m_widgetDescriptionVisibilityPlayback); m_widgetDescriptionVisibilityPlayback.reset(); } //将小组件描述设置成描述文本。描述取自小组件节点。 string widgetDescription = m_selectedItem->getProperty(*m_widgetDescriptionPropertyType); m_widgetDescriptionTextBlock->setText(widgetDescription); //将Widget Description Layer 设置为可见。 m_widgetDescriptionNode->setVisible(true); } }
onProjectLoaded()
函数中注册 Widget Grid List Box 节点的 ItemSelectedMessage
消息处理程序。virtual void onProjectLoaded() KZ_OVERRIDE
{
...
//添加选择3D 网格列表框 (Grid List Box 3D) 项事件的消息处理程序。
m_widgetList->addMessageHandler(GridListBox3D::ItemSelectedMessage, bind(&ProgrammerTutorialApplication::onListBoxItemSelected, this, placeholders::_1));
}
当点击小组件时,应用程序使用指定的两个动画高亮显示小组件,让 Widget Description Layer 节点可见,并在 Widget Description Layer 中显示小组件描述。